Interrupt - Programmierung

← Zurück zum Forum

Ich mache mal ein neues Thema auf, weil ich es so spannend finde. Und habe gleich eine Frage:

Als junger Kerl habe ich viel im Basic programmiert. Für meinen Mathekurs habe ich dann in Basic eine Kurvendiskussion geschrieben, mit grafischer Darstellung der Kurve. Man konnte via INPUT eine beliebige Funktion eingeben, der Rechner hat sie dann in einem Koordinatensystem gezeichnet. Mein Problem damals war: Wie bekomme ich die Funktion in das Programm? Die Lösung: Ich positioniere den String mit der durch INPUT eingegebenen Funktion auf den Bildschirm, positioniere den Curser oberhalb des Strings, unterhalb des Strings kommt ein Befehl auf dem Bildschirm CONT, dann ein paar Returns in den Tastaturbuffer und das Programm stoppen. Der Curser läuft über den String (mit Zeilennummer), speichert ihn ins Programm und durch den Befehl CONT startet das unterbrochene Programm wieder. Dann kann die Funktion gezeichnet werden. Jetzt die Frage: Kann ich in meinem Assemblerprogramm etwas in den Tastaturbuffer speichern und löse damit den Tastaturinterrupt aus?? Also es geht um die Auslösung des Tastaturinterrupts ohne eine Taste zu drücken... Gruß Peter

AntwortZitat

Folgende Möglichkeit eines weiteren Interrupt, den man sehr schön in seinem Programm nutzen kann habe ich gerade entdeckt und ausprobiert: Der Break-Interrupt!!!

Folgende Idee: Der VBI ist ja so schön, da er kontinuierlich 5 x pro Sekunde ausgelöst wird. Viele Steuerungen können so im VBI super programmiert werden, leider ist halt irgendwann Schluss! Den VBI aufzuteilen geht, aber dann wird die Steuerung träge und die Schüsse laufen langsamer, was man dann wieder aufwendig abfangen muss. Insgesamt sind da klare Limitationen. Die möglichen ca. 1600 Befehle gehen auch nur bei 50 Hz und ab ca. 600 Befehle wirds dann langsam instabil - da das ja noch den Bildschirmaufbau betrifft, bekommt man mit zunehmender Länge des Programmes im VBI Probleme mit der Bildstabilität. Also dachte ich mir folgendes: Warum nicht den schönen VBI als Timer für einen anderen Interrupt nutzen. Der Tastaturinterrupt wäre möglich, man muss aber dann per Programm einen Tastendruck simulieren - habe ich jetzt noch nicht hinbekommen, geht bestimmt. Wir haben aber noch den Break-Interrupt .... und der geht! Immer wenn ein Maschinenprogramm auf einen Break-Befehl trifft, wird der Interrupt ausgelöst - und die Vektoren kann man abfangen und entsprechend umbiegen:

Der BRK - Befehl steht einfach im VBI und löst somit 5x pro Sekunde den Interrupt aus!

.proc vbinter2          

            pha
            txa
            pha
            tya
            pha

            brk

            ...
            weiterer Code


Vor dem Hauptprogramm wird der alte Vektor gerettet und der neue ins Register reingeschrieben:

            mwa vbreak breakin
            mwa #tastaturi vbreak   

Dann einfach die Subroutine einfügen (unterhalb des Hauptprogrammes - dieses selber wird gar nicht verändert)

.proc tastaturi

            pha
            txa
            pha
            tya
            pha

            ...

            hier steht der Code (z.B. die Missiles)
            ...

            pla
            tay
            pla
            tax
            pla
            jmp (breakin)


    .endp


getestet und funktioniert... 😉

AntwortZitat

Hallo Peter!

Der VBI ist genauso oft wie die Hz-Zahl des Bildschirmaufbaus. Also 50Hz oder 60Hz, dass sind 50x in der Sekunde oder 60x in der Sekunde. Du kannst sicherlich einen weiteren Interrupt innerhalb eines Interrupts aufrufen, nur wird das nichts daran ändern, dass Du nur eine bestimmte Anzahl an Maschinenzyklen in der gleichen Zeit hast. Zumal wenn Du ein Objekt innerhalb eines VBIs mehrfach bewegst, diese Bewegung nicht angezeigt wird, weil der Bildschirm nicht erneut aufgebaut wurde, dann kannst Du das Objekt gleich zwei oder drei Schritte auf einmal machen lassen.

Ich denke mit dem Ansatz kommst Du nicht besonders weit und statt BRKs könntest Du auch JSRs nutzen.

Grüße Janko

Meine Projekte findest Du hier...

AntwortZitat

Hallo Janko, prinzipiell hast du Recht, ich komme nicht viel weiter, aber ich komme damit ein wenig weiter.... Ich habe jetzt den langen VBI in 2 VBI´s geteilt und die Schüsse und die Steuerung so modifiziert, daß sie immer 2 y / x-Werte weiter gehen. Zusätzlich habe ich jetzt nochmal ca. 200-300 Programmcodes frei im BRK-Interrupt, der dann auch jeweils vom 2. VBI gesteuert wird - also 2.5x pro Sekunde (nicht 5x) - hier habe ich experimentiert und es funktioniert... mache ich mehr Code in den BRK Interrupt, friert der Atari komplett ein. Ich hoffe, daß ich so aber noch ganz bequem die Soundsteuerung unterbringen kann... mehr brauche ich nicht, der Rest läuft im Hauptprogramm. Ich programmiere das mal durch und stelle dann den Code hier online... Gruß Peter

AntwortZitat

Das waren damals keine Returns im Tastaturbuffer, sondern eher dieser eine simple POKE, der die Taste Return dauerhaft ausgelöst hat, solange der Editor E: aktiv war.

Schau mal bitte in das Atari Profibuch Seite 162.

http://fujiama.eu https://abbuc.de/~atarixle/ BOSS-X - das Finale: https://abbuc.de/~atarixle/?article=bossxfinaleditionprerelease

AntwortZitat

... hm ja, verstehe. Mit dem Editor bin ich allerdings auch noch nicht so firm. Wenn ich das richtig gelesen habe, dann kann ich per Software keine Tastaturaktion simulieren und so den Interrupt auslösen??

AntwortZitat

Hallo Peter!

Ich bin ja ein kleiner Fan von Peter Finzel und kann Dir nur empfehlen "die Hexenküche" zu lesen. Da wird sehr viel über Interrupts erklärt. Auch sehr schön ab Seite 47 der Abschnitt "Wie schnell ist Ihr ATARI?".

Grüße Janko

Meine Projekte findest Du hier...

AntwortZitat

Tatsächlich habe ich den Artikel bereits mehrfach gelesen und finde ihn gut - ich habe die Hexenküche original hier und übrigens auch eine alte Originalausgabe von DeRe - auch ein interessantes Buch. Über die Interruptprogrammierung - also so richtig in die Tiefe - findet man leider nicht so viel.. Lieben Dank und Gruß Peter

... aus dem wie schnell der Atari ist, habe ich ja auch entnommen, wie viele Befehle in in den VBI stecken kann - leider auch alles ein wenig Theorie, denn ab ca. 500-600 Befehlen wirds dann zunehmend instabil

AntwortZitat

ich habe das Buch folgendermaßen verstanden, grob beschrieben sollte man so vorgehen: Positionen von Playern, Missiles, Landschaft in der Hauptroutine berechnen, und dann im Interrupt nur "setzen", bzw abwechselnd Bilder aufbauen und jeden 2. Interrupt wechseln.

In der Hauptroutine hast Du ewig Zeit für komplizierte Berechnungen, solltest aber keine P/M/DL "zeichnen" oder "Löschen", dann flackert das Bild.

AntwortZitat

... dies ist ja mein erstes Projekt dieser Art und natürlich sammelt man da so seine Erfahrungen. Primär wollte ich anhand dieses Spieles Assembler lernen und den Atari noch besser verstehen lernen... daß das so kompliziert wird und daß ich im Prinzip bei diesem komplexen Programm alles ziehen muss, ahnte ich zu Beginn nicht. Mein nächstes Projekt werde ich ganz anders aufbauen und diesen Artikel werde ich gut studieren. Ich habe jetzt in den letzten Wochen viel experimentiert und muss feststellen: Um alles so machen zu können, wie ich es vor hatte, müsste ich alles komplett umbauen ... das macht jetzt keinen Sinn. Ich mache ein paar Abstriche - es wird nur 2 Missiles geben, die Landschaft wird nicht 15 Minuten scrollen, sondern weniger, dafür baue ich andere Dinge noch ein. Ich möchte das Projekt wirklich abschließen und ein schönes spielbares Programm rausbringen. Caverns of Mars I war auch viel einfacher, als Phobos... Ich finde es aber echt toll, wie Ihr hier auch mitlest oder mit immer wieder Tips gebt. Am Ende möchte ich einen guten Code haben, der zwangsläufig viele Aspekte berücksichtigt: Feinscrolling, P/M Grafik, Animationen, Aufbau Landschaft / Speicher, Interrupts, Displaylist, Sound - incl. kleine Engine, die man ins Programm einbinden kann... vielleicht nehme ich die SFX und modifiziere sie... einen guten Sprite/ Landschaftsteile Editor habe ich heute Dank Mathy gefunden. Alles möchte ich dann hier in einem Extrablock incl. Assemblercode zusammenstellen und veröffentlichen... vielleicht macht man sogar ein kleines Lernscript daraus, was frei verfügbar ist. Für alle und natürlich kostenlos..... Liebe Grüße Peter

AntwortZitat

Grundsätzlich ist es also das Problem des Timings.... In dem Artikel wird ja beschrieben, wie der VBI Teile der Hauptroutine steuert... Ein Problem dabei ist wohl, daß der VBI viel schneller läuft als das Hauptprogramm... wenn eine Schleife im Hauptprogramm auf den VBI wartet, dann ist der vielleicht schon ein paar mal durchgelaufen. Allerdings habe ich zur Zeit immer ein Problem mit der Kollision, denn wenn der Missile kollidiert und das dann an das Hauptprogramm weitergegeben wird, dann läuft er ja schon etwas weiter (weil der VBI schneller ist) und überschreibt die Kollision mit etwas anderem...

AntwortZitat

Bist du dir sicher, dass deine Hauptprogrammschleife länger braucht, als 1/50 Sekunde, der Zeit zwischen zwei VBIs?

Teste es doch einfach mal: Lies RTCLOK+2 am Beginn und Ende deiner Schleife aus und vergleich die Werte. Dann siehst du, wieviele VBIs dazwischen vergangen sind weil RTCLOK+2 innerhalb jedes VBIs inkrementiert wird.

Das Zeitproblem im VBI ist ja nicht, dass du die 1/50 Sekunde überschreitest, sondern dass du innerhalb des VBIs nur den kurzen Zeitraum hast, den der (vermutlich inzwischen virtuelle) Kathodenstrahl benötigt, um von rechts unten nach links oben geschwenkt zu werden.

Du hast zwei Möglichkeiten, dich zu synchronisieren.

Entweder für die komplette Hauptschleife, was sinnvoll ist, wenn sie deutlich weniger Zeit benötigt, als die 1/50 Sekunde und du nicht willst, dass sie schneller abläuft.

Oder, wie in meinem Beispiel im anderen Thread, du baust die Dinge, die gezielt innerhalb jeder 1/50 Sekunde einmal (aber nicht exakt synchron, wie im VBI) passieren müssen, in ein Unterprogramm ein, das du (ggf. auch mehrfach) aus deinem Hauptprogramm aufrufst. Da passen z.B. die Kollisionsabfragen rein oder auch Änderungen auf dem gerade nicht sichtbaren Bildschirm, falls du mittels Page-Flipping bzw. Double-Buffering arbeitest. Der mehrfache Einbau der Unterprogramme hat dann Sinn, wenn dein Hauptprogramm tatsächlich mehr Zeit verschlingt, als 1/50 Sekunde.

Mini-Codebeispiel für die Variante Hauptschleife:

; Programmbeginn

; Hauptschleife
main
    lda RTCLOK+2
    sta startzeit       ; Ein Byte, das du irgendwo allokiert hast.

; Hier kommt deine Hauptschleife mit all den zeitaufwändigen Aufgaben rein.

; Warte darauf, dass der VBI ausgeführt wird.
; Falls der Schleifendurchlauf langsamer war, geht's direkt weiter weil RTCLOK+2 bereits inkrementiert wurde.
    lda startzeit
warte
    cmp RTCLOK+2
    beq warte

; Und es geht von vorne los.
    jmp main

Mini-Codebeispiel für die Variante Unterprogramm (analog zum RtP Thread) minimal erweitert: Die Unterprogramme steuer dabei selbst, dass sie zwischen zwei VBIs nur einmal ausgeführt werden. Jeder weitere Aufruf innerhalb dieser Zeit führt zu einem direkten RTS.

; Programmbeginn

; Stell einen definierten Anfangszustand her.
; Ansonsten kann es sein, dass der erste Durchlauf stottert.
    lda RTCLOK+2
    sta letzter_durchlauf1      ; Ein Byte, das du irgendwo allokiert hast.
    sta letzter_durchlauf2
    ; und ggf. für weitere Unterprogramme

; Hauptschleife

main
; Wieder deine Hauptschleife mit all den zeitaufwändigen Aufgaben.
    jsr tue_dieses
    jsr kollisionen ; VBI-synchronisiert
    jsr bildschirmaufbau_double_buffer  ; VBI synchronisiert
    jsr tue_jenes
    jsr mach_was_tolles ; das ganz lang dauert
    jsr kollisionen ; VBI-synchronisiert; ein zweites Mal, falls "mach_was_tolles" zu lange gebraucht hat
    jsr bildschirmaufbau_double_buffer  ; VBI synchronisiert

; Und es geht von vorne los.
    jmp main

kollisionen
    lda RTCLOK+2    ; wird im Stage 1 VBI automatisch inkrementiert
    cmp letzter_durchlauf1
    bne mach_weiter1
    rts
mach_weiter1
    sta letzter_durchlauf1
; Berechne die Kollisionen und merk die Ergebnisse für die Umsetzung im VBI
    rts

bildschirmaufbau_double_buffer
    lda RTCLOK+2    ; wird im Stage 1 VBI automatisch inkrementiert
    cmp letzter_durchlauf2
    bne mach_weiter2
    rts
mach_weiter2
    sta letzter_durchlauf2
; Bau denzweiten Bildschirm auf, dass du im VBI umschalten kannst.
    rts

AntwortZitat

Ich glaube auch, daß ich prinzipiell mehr Zeit in der Hauptschleife hätte, wobei da schon ne Menge Code drin ist... wahrscheinlich liegt es in der primären Konzeption! Ich habe ja den gesamten Grob-/Feinscroll in der Hauptroutine. Der Grobscroll ist bei mir so aufgebaut, dass er den gesamten Bildschirm um eine Reihe verschiebt - und das braucht Zeit. Der Feinscroll ist da natürlich viel schneller und damit das flüssig läuft, habe ich da m ittels RTCLOK schon jeweils bei jeder Feinscrollausführung eine Warteschleife drin. Das bremst die Hauptschleife natürlich enorm aus. Ich müsste also den Grobscroll schneller machen und so konzipieren, daß er nicht den ganzen Bildschirm hochscrollt, sondern nur die Bildschirmvektoren umbiegt. Das wäre sicherlich sinnvoll ... aber ich habe ja die letzte Reihe so aufgebaut, daß sie quasi komprimierte Daten aus dem Speicher holt und die letzte Landschaftreihe quasi daraus immer aufbaut. In der anderen schnellen Version würden ich ja nur quasi den Computerspeicher "abfahren" und bei 980 Byte proBildschirm wäre dann nach 20-25 Bildschirmzyklen (a ca 5 Sekunden) nach ca. 2 Minuten Scrollzeit der Speicher voll... so schaffe ich ca. 10-15 Minuten. Tales Of Beta Lyrae zB hat wahrscheinlich genau aus diesem Grund einen komplexen Zufallsgenerator für die Landschaft generiert... da hat man dann nicht so ein Speicherproblem. Und bei Phobos hört der automatische Scroll dann irgendwann auf und man fährt langsam durch die Lande... wahrscheinlich genau aus diesem Grund. Ich müsste alles komplett umkonzipieren.....
Lieben Gruß Peter

AntwortZitat

Prodehl schrieb: Ich müsste also den Grobscroll schneller machen und so konzipieren, daß er nicht den ganzen Bildschirm hochscrollt, sondern nur die Bildschirmvektoren umbiegt. Das wäre sicherlich sinnvoll ... aber ich habe ja die letzte Reihe so aufgebaut, daß sie quasi komprimierte Daten aus dem Speicher holt und die letzte Landschaftreihe quasi daraus immer aufbaut.

Wenn du jede Bildschirmzeile in der Displaylist mit einer Adresse versiehst, anstatt nur der ersten (und ggf. der nach 4 KB), kannst du beides haben.

Du schiebst dann die Adressen der jeweiligen Bildschirmzeilen durch die Displaylist durch und baust die letzte Zeile nicht speichertechnisch "ganz hinten" auf, sondern an der Adresse auf die die letzte Zeile in der Displaylist gerade zeigt.

AntwortZitat
.proc wartes
            clc
            ldx delay ; Warteschleife
st              lda RTCLOK+2    
wa              cmp RTCLOK+2    
                beq wa    
                dex            
                bpl st 
                rts
        .endp

            ; -------------------------------------------------------------------------------------

    .proc feinscroll
            ldy #1
            mva #0 delay
@           jsr wartes

            sty vscrol
            iny
            cpy #8
            bne @-      
            rts
        .endp   

so sieht mein Feinscroll und die zugehörige Warteschleife aus...

und so der Programmablauf ohne Warteschleife... rt2.1 2.MOV

Anhänge:
AntwortZitat

Hey DjayBee .... ganz 100% habe ich nicht verstanden, wie ich das umsetzen kann, aber prinzipiell habe ich es verstanden... ja, das wird wohl die Lösung sein! Und dann läuft der Fein-/ und Grobscroll fast identisch schnell ab...

AntwortZitat

Das würde ich definitiv im VBI tun. Da musst du nicht explizit warten und Zyklen verbrennen, sondern bekommst schön alle 1/50 Sekunde einen Aufruf und kannst dann, bei einem delay von 0 wie in deinem obigen Beispiel, jedes Mal einen Finescroll durchführen.

Falls du den Grobscroll mittels Manipulation der Displaylist machen möchtest, weiß ich nicht, ob das kurz genug für einen VBI ist. Ggf. musst du dann mit zwei Displaylists arbeiten, diese im Hauptprogramm verändern (wenn VSCROL=7) ist und die jeweils neue Adresse in SDLSTL hinterlegen. Dann wird sie automatisch vom nächsten VBI aktiviert, in dem du dann VSCROL gleichzeitig auf 0 setzt.

Ich hab den Eindruck, dass du bei Rob von playermissile.com etwas abgeschaut hast. Lies dazu mal https://playermissile.com/scrolling_tutorial/index.html#interlude-vertical-blank-interrupts und den Code bei https://playermissile.com/scrolling_tutorial/index.html#code-walkthrough-2d-scrolling-with-dli (vom Wort DLI hier nicht irritieren lassen).

AntwortZitat

Prodehl schrieb: ... dies ist ja mein erstes Projekt dieser Art und natürlich sammelt man da so seine Erfahrungen. Primär wollte ich anhand dieses Spieles Assembler lernen und den Atari noch besser verstehen lernen... daß das so kompliziert wird und daß ich im Prinzip bei diesem komplexen Programm alles ziehen muss, ahnte ich zu Beginn nicht. Mein nächstes Projekt werde ich ganz anders aufbauen und diesen Artikel werde ich gut studieren. ... Ich habe jetzt in den letzten Wochen viel experimentiert und muss feststellen: Um alles so machen zu können, wie ich es vor hatte, müsste ich alles komplett umbauen ... das macht jetzt keinen Sinn. ... Ich finde es aber echt toll, wie Ihr hier auch mitlest oder mit immer wieder Tips gebt. Am Ende möchte ich einen guten Code haben, der zwangsläufig viele Aspekte berücksichtigt: Feinscrolling, P/M Grafik, Animationen, Aufbau Landschaft / Speicher, Interrupts, Displaylist, Sound - incl. kleine Engine, die man ins Programm einbinden kann... vielleicht nehme ich die SFX und modifiziere sie... einen guten Sprite/ Landschaftsteile Editor habe ich heute Dank Mathy gefunden. ...

Du hast schon SO VIEL gelernt und umgesetzt, das ist bewundernswert! Mach nur weiter und lass Dich nicht entmutigen. Es gibt viele gute Bücher, Beispiele, und oft mehr als einen Weg nach ROM, äh RAM, äh nee Rom. Das wird schon. Manchmal muss man auch noch mal von vorn anfangen, ging mir auch oft genug so. Aber bis dahin hat man viel gelernt und das hat man in Petto/in Reserve. Viel Kommentieren macht alten Code besser verständlich, auch so eine Erfahrung.

AntwortZitat

Hallo alle zusammen.

Wenn man das hier so verfolgt, glaube ich, Peter Du machst etwas verkehrt.

Nur mal mein "Sempf" dazu: - Du solltest Dein Programm nicht vollständig im VBI laufen lassen, da es hier zu viele Einschränkungen bzgl. der Zeit gibt. Im VBI sollten nur Dinge gemacht werden wie Feinscrolling oder das Zurücksetzen des Displaylist-Interrupts.

  • Erstelle beliebig viele kleine Displaylist-Interrupts, die nur die Farbe anpassen oder CHBASE verbiegen. Brauchst Du mehrere, verbiege am Ende VDSLST auf den nächsten DLI-Interrupt. Hast Du einen DLI zu viel oder zu wenig, der VBI richtet das, Dein Programm verabschiedet sich nicht gleich in die Jagdgründe.

  • Teile sämtliche Arbeiten in kleine unabhängige Routinen auf und lass diese von einer Main-Loop in der von Dir gewünschten Reihenfolge aufrufen. Wenn Du am Ende der Main-Loop bist, warte einfach bis VCOUNT==94 ist und beginne die Main-Loop wieder von vorne. So kannst Du Dein Programm syncron zu 1/50s oder 1/60s halten.

  • Willst Du nur jeden 10ten Interrupt eine der Routinen ausführen, dann decrementiere einen Counter innerhalb deiner Routine und wenn der Counter 0 ist, führe die Routine aus. Die Routine wird alle 1/50s gerufen, aber nur jeden 10ten Interrupt ausgeführt. Die paar extra-Zyklen für das Decrement und JSR/RTS sind nicht der Rede wert. Willst Du die Routine häufiger rufen, weil z.B. Schüsse in schnellerer Abfolge passieren sollen, dann setze einfach den Initialwert für den Counter runter. So klappt es dann auch mit unterschiedlichen Levels.

So bist Du auch in der Lage mehr zu machen, als wenn alles im VBI verwurstet ist. Du kannst länger laufende Routinen z.B. jeden 2. Main-Loop-Durchlauf laufen lassen und in der anderen Phase andere Dinge machen. Das Programm wirkt flott und bleibt aufgeräumt. Was Du vermeiden solltest, das die kleinen Routinen zu viele Dinge machen und länger als 1/50s laufen, dann solltest Du sie optimieren oder aufspalten. Und sollte Dein Programm doch anfangen zu ruckeln, ist evtl. Main-Loop-Durchlauf noch nicht optimal. Man muss nicht jede 1/50s den Score neu zeichnen. Das kann man prima machen, wenn Zeit da ist.

Du willst wissen, wie viel Zeit eine Deiner kleinen Routinen verbraucht. Zähle die Zeilen.(?) Dazu: warte bis VCOUNT >= 4 ist, setze die Hintergrundfarbe auf einen anderen Wert als Schwarz, führe Deine Routine aus, am Ende setzt du die Hintergrundfarbe wieder auf Schwarz. So bekommt man recht schnell einen Überblick über Routinen die recht lange brauchen. Wenn man beim VCOUNT min. bis 18 wartet, kann man sehr schön sehen, das es hier mehr Zeilen bedarf bis einfachste Routinen durchgelaufen sind. Willkommen im DMA-Dilemma.

Desweiteren sollten Dinge für die Player-Missiles immer außerhalb der gerade sichtbaren Zeile passieren, sonst kommt es vor, das Du der sichtbaren Zeile hinterher läufst und überhaupt nichts siehst. Oder das die Player-Missiles genau dazwischen liegen, dann kann es zum Versatz der horizontalen Position kommen. Musik kannst Du einfach mitten drin abspielen. Einfach die Routine aufrufen, die normalerweile im VBI gerufen werden sollte, wenn schon alles andere fertig gezeichnet ist. Läuft Deine Main-Loop syncron, wird es auch die Musik sein.

Refaktorisiere die Routinen und spalte sie auf in Typen wie "die Zeichnen" und "die Rechnen". Rechnen kannst Du auch wenn der Schirm dargestellt wird, Zeichnen aber sollte besser außerhalb gerufen werden.

Noch ein Tipp, falls Dein Programm noch ein Quentchen mehr Zeit braucht. Verzichte auf WSYNC in den Displaylist-Interrupts. Hier sollte man sehen, das die DLIs zur richtigen Zeit ausgelöst werden ggf. die Reihenfolge der LDA/STA anpassen. WSYNC sollte das letzte Mittel bleiben. Und wenn sich auf dem Schirm viel bewegt, stört ein Farbwechsel am Rand wenig, hier hilft dann ein gezieltes NOP. Den DMA für die PM-Grafik kann man auch im DLI einschalten, wenn man die PM-Grafik braucht und am Ende, wenn die letzte Zeile der PM-Grafik gezeichnet wurde wieder abschalten. Das spart ca. 5 Zyklen pro nicht darzustellender Zeile. Was nicht geht ist den DMA komplett abzuschalten und im DLI dann wieder versuchen einzuschalten, das funktioniert nicht. Da spreche ich aus Erfahrung 😉 Du kannst auch CRITIC auf 1 setzen und die Dinge die alle im 2. VBI passieren abstrippen und nur was Du wirklich brauchst nachprogrammieren. Aber ich mache das meist nicht. Ist mir zu aufwendig.

Einen Vorteil bringt das obige noch: Dein Programm sollte auch bei 1/60s im NTSC-Mode noch laufen, wenn Du alles richtig gemacht hast. Wenn es jetzt ruckelt, kannst Du das Programm noch weiter optimieren. Die 1/60s NTSC-Jungs werden es Dir danken.

Schönen Abend Lars

AntwortZitat

Guten Morgen Lars! Vielen Dank für die vielen interessanten Anregungen! Als ich vor ein paar Monaten gestartet bin, war mein Ziel eigentlich Assembler zu lernen, dabei das System mehr kennenzulernen und dabei einen einfachen Shooter nach dem Vorbild Phobos zu schreiben. Eigentlich könnte ich jetzt aufhören und mit meinen gesammelten Erfahrungen was ganz anderes machen, irgendwie möchte ich aber das Projekt zu Ende bringen.... Am Anfang habe ich relativ unbedarft angefangen und drauf los programmiert... ganz ohne VBI und DLI. Allerdings braucht man den VBI zwingend und die Vorteile des VBI haben mich wohl verleitet zu viel da reinzupacken... in der Hoffnung, daß ich es kann. Es geht auch, aber das. System wird dann instabiler ab ca. 600 Befahle. Allerdings ist mein Programm mittlerweile ja recht strukturiert! Ich habe tatsächlich eine relativ einfache Hauptschleife und diese Hauptschleife ruft viele kleine Unterprogramme wiederkehrend auf. Der Code ist auch entsprechend geschachtelt. und aufgebaut, so daß ich den Überblick behalte. Der VBI ist gar nicht so lang - im VBI mache ich die Joystickabfrage und die ganze PM-Steuerung und Berechnung incl. Kollision. Das wars. Das Feinscroll mit Grobscroll läuft. im Hauptprogramm. Das geht auch nicht anders, weil ich den Grobscroll so aufgebaut habe, daß er den gesamten Bildschirm um eins nach oben schiebt - für den VBI wäre das zu lang. Die Crux ist leider dabei, daß ich dann Warteschleifen für den Feinscroll brauche und dadurch läuft das Hauptprogramm langsamer als der VBI. Die notwendige Syncronisierung läuft also nicht. Den Grobscroll habe ich so. gemacht, weil ich den Landschaftsaufbau (meine "Letzte Reihe") komprimiert habe und aus Landschaftsdaten quasi berechne - daher kann ich den Grobscroll nicht einfach so über den Atarispeicher bewegen. Ich müsste dafür die DL ständig verändern und anpassen - diese Möglichkeit habe ich erst vor ein paar Tagen kennengelernt. Das mache ich im nächsten Projekt, denn da müsste ich das aktuelle Programm quasi fast völlig neu konstruieren - habe ich probiert mit dem Ergebnis, daß nichst mehr stabil läuft... je mehr ich jetzt grundsätzlich ändere, desto schlechter wird es. Da hilft nur. eine fast komplette Neukonzeption...
Aber alle deine Einwände sind natürlich berechtig und die werde ich beim nächsten Projekt unbedingt berücksichtigen. Hauptprogramm und VBI zu syncronisieren macht absolut Sinn -auch du wirst deine Erfahrungen gesammelt haben 😉 Und ich muss mich dann auch intensiv mit dem DLI beschöäftigen... ! Liebe Grüße Peter

AntwortZitat

... so sieht beispielsweise meine Hauptschleife im Moment aus:

hauptprogramm

            jsr schuesse
            jsr blinken
            jsr letztereihe         ;letzte Reihe (lands) Bildschirm1 printen (sichtbar)    
            jsr feinscroll          ;Feinscroll Bildschirm1 ausführen (sichtbar)        
            mwa #$7530 var1         ;var1 auf 30000 ($7530) setzen
            mwa #$7AE4 var2         ;var2 auf 31460 ($7AE4) setzen
            jsr grobscroll          ;Bildschirm1 kopieren + grobscroll
            mwa #$7b0C var1         ;var1 + var2 auf 31500 ($7B0C) setzen
            mwa #$7b0C var2
            jsr umschalten
            jsr incfuelzaehler
            jsr letztereihe         
            jsr feinscroll          ;Feinscroll Bildschirm2 ausführen (sichtbar)                        
            mwa #$7508 var2         ;var1 auf 29960 ($7508) setzen
            mwa #$7b0C var1         ;var2 auf 31500 ($7B0C) setzen
            jsr grobscroll          ;;Bildschirm2 kopieren + grobscroll
            mwa #$7530 var1         ;var1 + var2 auf 30000 ($7530) setzen
            mwa #$7530 var2
            jsr umschalten          ;umschalten auf Bildschirm1 - Bildschirm1 wird sichtbar
            jsr kollmissile
            jsr incfuelzaehler

            ;Ende der Bildschirmausführung / Kontrolle Durchläufe
            sec
            lda #45     ; - 36 = Anzahl der Durchläufe - auf 4 beschränkt, da die Landschaft noch rudimentär ist und sich dann wiederholen soll
            sbc var6+1
            bpl @+
            jmp start1          ;Stop hier
@       
            jmp hauptprogramm               ;weiter
AntwortZitat